package com.etrans.baf.analyse.task.alarm.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import com.etrans.baf.analyse.task.track.service.TouristService;
import com.etrans.baf.analyse.util.DateUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

@Service
public class DataQualityService {
	@Autowired
	private MongoTemplate egovMongoTemplate;//引入配置的mongod模版
	@Autowired
	private TouristService touristService;
	
	static final Logger logger = LoggerFactory.getLogger(DataQualityService.class);
	
	final byte C_GPS_FLAG_VALID = 0x02; 
	/**
	 * 数据质量分析
	 * 一、轨迹数据质量
	 *  持续按照固定格式上报间隔传输，无变化；
	 *	轨迹数据持续无盲区；
	 *	轨迹数据的状态字或报警字固定，无变化；
	 *	轨迹定位速度大于0，但一直固定无变化；
	 *	正常运营车辆速度持续为0，无变化。
	*/
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void trackDataAnalyse() {
		String tableName = "gps_info_"+DateUtils.getDateTimeString(DateUtils.getPreviousDayDate(),"yyMMdd");
		List<Map<String,Object>> result =touristService.getVehicleInfo();
		Aggregation agg = Aggregation.newAggregation(
                Aggregation.group("vehicle_id").push("state").as("state")
                .push("rcv_time").as("rcvtime").push("gps_speed").as("speed")
        ); 
		AggregationResults<HashMap> outputType=egovMongoTemplate.aggregate(agg, tableName, HashMap.class);
		List<HashMap> lists=outputType.getMappedResults();
		for(Map v:result){
			Integer vehicleid = Integer.valueOf(v.get("id").toString());
			lists.forEach(m->{
				Integer vid = (Integer)m.get("_id");
				if(vid.equals(vehicleid)){
					List<Date> arr_time=(ArrayList<Date>) m.get("rcvtime");
					analyseRcvTime(arr_time,v);
					List<Integer> arr_speed=(ArrayList<Integer>) m.get("speed");
					analyseGpsSpeed(arr_speed,v);
					List<Integer> arr_state = (ArrayList<Integer>) m.get("state");
					analyseState(arr_state,v);
					analyseStateValid(arr_state,v);
				}
			});
		}
	}
	
	/**
	 * 数据质量分析
	 * 二、上报报警异常（疲劳报警、凌晨2-5点报警） 判断一天内 是否有产生
	 *  下级平台上报了某种报警但上级平台在对应时间却未分析出此种报警；
	 *  上级平台分析出某种报警但相应时间点下级平台未上报此报警 ；
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void alarmDataAnalyse() {
		String tableNameA = "alarm_analyse_"+DateUtils.getDateTimeString(DateUtils.getPreviousDayDate(),"yyMMdd");
		String tableNameI = "alarm_info_"+DateUtils.getDateTimeString(DateUtils.getPreviousDayDate(),"yyMMdd");
		List<Integer> alarmTypeList = new ArrayList<>();
		alarmTypeList.add(2);
		alarmTypeList.add(14);
		Criteria c = new Criteria();
		c.and("alarm_type").in(alarmTypeList);
		Aggregation agg = Aggregation.newAggregation(
				Aggregation.match(c),
                Aggregation.group("vehicle_id").push("alarm_type").as("alarm_type")
                .first("vehicle_no").as("vehicle_no").first("vehicle_color").as("vehicle_color")
                .first("gnsscenter_id").as("gnsscenter_id").first("platform_id").as("platform_id")
                .first("area_id").as("area_id").first("enterprise_id").as("enterprise_id")
        ); 
		AggregationResults<HashMap> outputType=egovMongoTemplate.aggregate(agg, tableNameA, HashMap.class);
		List<HashMap> lists=outputType.getMappedResults();
		Aggregation ag = Aggregation.newAggregation(
                Aggregation.group("vehicle_id").push("alarms").as("alarms")
        ); 
		AggregationResults<HashMap> output=egovMongoTemplate.aggregate(ag, tableNameI, HashMap.class);
		List<HashMap> result=output.getMappedResults();
		List<Integer> vehicleList = new ArrayList<>();
		for(Map v:lists){
			Integer vid = (Integer)v.get("_id");
			List<Integer> alarmType = (List<Integer>) v.get("alarm_type");
			result.forEach(r->{
				Integer vehicleid = (Integer)r.get("_id");
				String strAlarm = "";String str1="";String str2="";
				boolean flag = true,flagt = true;
				if(vehicleid.equals(vid)){
					if(!vehicleList.contains(vehicleid)){
						vehicleList.add(vehicleid);      // 存储 alarm_info_ 的车辆id
					}
					List<HashMap> arr_alarms=(ArrayList<HashMap>) r.get("alarms");
					if(alarmType.contains(2)){
						for(int i=0;i<arr_alarms.size();i++){
							flag =arr_alarms.get(i).toString().contains("alarm_type=2");
							str1= "上级平台疲劳报警,下级平台无疲劳报警;";
						}
					}
					if(alarmType.contains(14)){
						for(int i=0;i<arr_alarms.size();i++){
							flagt =arr_alarms.get(i).toString().contains("alarm_type=14");
							str2= "上级平台禁行报警,下级平台无禁行报警;";
						}
					}
				}
				strAlarm=str1+str2;
				if(!flag||!flagt){
					String tableName = "data_quality_analyse";
					 DBObject entity = new BasicDBObject();
					 entity.put("vehicle_id",vid);
					 entity.put("vehicle_no",v.get("vehicle_no"));
					 entity.put("vehicle_color",v.get("vehicle_color"));
					 entity.put("gnsscenter_id", v.get("gnsscenter_id"));
					 entity.put("platform_id", v.get("platform_id"));
					 entity.put("area_id", v.get("area_id"));
					 entity.put("enterprise_id",v.get("enterprise_id")==null?1:Integer.valueOf(v.get("enterprise_id").toString()));
					 entity.put("exception_time", DateUtils.getPreviousDayDate());
					 entity.put("exception_type", 2);
					 entity.put("exception_content", strAlarm);
					 egovMongoTemplate.insert(entity, tableName);
				}
			});
		}
		for(Map v:lists){
			Integer vid = (Integer)v.get("_id");
			List<Integer> alarmType = (List<Integer>) v.get("alarm_type");
			if(!vehicleList.contains(vid)){
				String str="",str1="",str2="";
				if(alarmType.contains(2)){
					str1= "上级平台疲劳报警,下级平台无疲劳报警;";
				}
				if(alarmType.contains(14)){
					str2= "上级平台禁行报警,下级平台无禁行报警;";
				}
				str=str1+str2;
				String tableName = "data_quality_analyse";
				 DBObject entity = new BasicDBObject();
				 entity.put("vehicle_id",vid);
				 entity.put("vehicle_no",v.get("vehicle_no"));
				 entity.put("vehicle_color",v.get("vehicle_color"));
				 entity.put("gnsscenter_id", v.get("gnsscenter_id"));
				 entity.put("platform_id", v.get("platform_id"));
				 entity.put("area_id", v.get("area_id"));
				 entity.put("enterprise_id",v.get("enterprise_id")==null?1:Integer.valueOf(v.get("enterprise_id").toString()));
				 entity.put("exception_time", DateUtils.getPreviousDayDate());
				 entity.put("exception_type", 2);
				 entity.put("exception_content", str);
				 egovMongoTemplate.insert(entity, tableName);
			}
		}
	}
	/**
	 * 数据质量分析
	 * 三、拍照异常
	 * 
	 *	
	 */
	@SuppressWarnings("unchecked")
	public void imageDataAnalyse() {
		List<Map<String,Object>> result =touristService.getVehicleInfo();
		analyseHisImage(result);
		analysePhoto(result);
	}
	/**
	 * 历史照片中出现多次（>=2次）照片完全相同的现象。
	 * @param result
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void analysePhoto(List<Map<String, Object>> vehicles) {
		String tableNames = "img_info_"+DateUtils.getDateTimeString(DateUtils.getPreviousDayDate(),"yyMMdd");
		Aggregation agg = Aggregation.newAggregation(
                Aggregation.group("vehicle_id").push("unique").as("flags")
        ); 
		AggregationResults<HashMap> outputType=egovMongoTemplate.aggregate(agg, tableNames, HashMap.class);
		List<HashMap> lists=outputType.getMappedResults();
		for(Map v:vehicles){
			Integer vehicleid = Integer.valueOf(v.get("id").toString());
			lists.forEach(m->{
				Integer vid = (Integer)m.get("_id");
				String str = "";
				if(vid.equals(vehicleid)){
					boolean flag =false;
					List<String> flags=(ArrayList<String>) m.get("flags");
					Map<String,Integer> temp = new HashMap<>();
					for(int i=0;i<flags.size();i++){
						if(temp.get(flags.get(i))!=null){
							str="历史照片中出现多次照片完全相同的现象";
							flag =true;
						}else{
							temp.put(flags.get(i), 1);
						}
					}
					if(flag){
						String tableName = "data_quality_analyse";
						 DBObject entity = new BasicDBObject();
						 entity.put("vehicle_id", Integer.valueOf(v.get("id").toString()));
						 entity.put("vehicle_no",v.get("vehicleno"));
						 entity.put("vehicle_color",v.get("vehiclecolor"));
						 entity.put("platform_id", v.get("platformid"));
						 entity.put("area_id", v.get("areaid"));
						 entity.put("enterprise_id",v.get("enterpriseid")==null?1:Integer.valueOf(v.get("enterpriseid").toString()));
						 entity.put("exception_time", DateUtils.getPreviousDayDate());
						 entity.put("exception_type", 3);
						 entity.put("exception_content", str);
						 egovMongoTemplate.insert(entity, tableName);
					}
				}
			});
		}
	}

	/**
	 * 无照片数据应答连续次数>=5次；
	 * 多次（>=2次）拍照应答图片均无变化；
	 * @param result
	 * 拍照失败应答标识
	 *	0x00：不支持拍照相；
	 *	0x01：完成拍照；
	 *	0x02：完成拍照、照片数据稍后传送；
	 *	0x03：未拍照（不在线）；
	 *	0x04：未拍照（无法使用指定镜头）；
	 *	0x05：未拍照（其他原因）；
	 *	0x09：车牌号码错误。
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void analyseHisImage(List<Map<String, Object>> vehicles) {
		String startTime = DateUtils.getDayStart(DateUtils.getPreviousDayDate());
		String endTime = DateUtils.getDayEnd(DateUtils.getPreviousDayDate());		
		Criteria c = new Criteria();
		c.and("gps_time").gte(startTime).lte(endTime);
		Aggregation agg = Aggregation.newAggregation(
                Aggregation.group("vehicle_id").push("photo_rsp_flag").as("flags").push("lens_id").as("channel")
        ); 
		AggregationResults<HashMap> outputType=egovMongoTemplate.aggregate(agg, "img_exception", HashMap.class);
		List<HashMap> lists=outputType.getMappedResults();
		
		for(Map v:vehicles){
			Integer vehicleid = Integer.valueOf(v.get("id").toString());
			lists.forEach(m->{
				Integer vid = (Integer)m.get("_id");
				String str = "";
				if(vid.equals(vehicleid)){
					boolean flag =false;
					int[] countNoReply=new int[]{0,0,0,0},countNoChang=new int[]{0,0,0,0};
					List<Integer> flags=(ArrayList<Integer>) m.get("flags");
					List<Integer> channel=(ArrayList<Integer>) m.get("channel");
					for(int i=0;i<flags.size();i++){
						if(flags.get(i)==1){  // 完成拍照 置空
							countNoChang[channel.get(i)]=0;
							countNoReply[channel.get(i)]=0;
						}else if(flags.get(i)==2){    
							countNoChang[channel.get(i)]++;
							countNoReply[channel.get(i)]++;
						}else{
							countNoChang[channel.get(i)]++;
						} 
					}
					for(Integer i:countNoChang){
						if(i>=2){
							str="多次拍照应答图片均无变化";
							flag =true;
						}
					}
					for(Integer i:countNoReply){
						if(i>=5){
							str="无照片数据应答连续次数超过5次";
							flag = true;
						}
					}
					if(flag){
						String tableName = "data_quality_analyse";
						 DBObject entity = new BasicDBObject();
						 entity.put("vehicle_id", Integer.valueOf(v.get("id").toString()));
						 entity.put("vehicle_no",v.get("vehicleno"));
						 entity.put("vehicle_color",v.get("vehiclecolor"));
						 entity.put("platform_id", v.get("platformid"));
						 entity.put("area_id", v.get("areaid"));
						 entity.put("enterprise_id",v.get("enterpriseid")==null?1:Integer.valueOf(v.get("enterpriseid").toString()));
						 entity.put("exception_time", DateUtils.getPreviousDayDate());
						 entity.put("exception_type", 3);
						 entity.put("exception_content", str);
						 egovMongoTemplate.insert(entity, tableName);
					}
				}
			});
		}
		
	}

	/**
	 * 分析接收时间间隔
	 * @param rcvTime
	 */
	public void analyseRcvTime(List<Date> rcvTime,Map<String,Object> vehicleInfo){
		logger.info("分析车辆  :"+vehicleInfo.get("id")+" 接收时间间隔");
		boolean flag = true;
		for(int i=1;i<rcvTime.size()-1;i++){
			int second = DateUtils.SecondsBetween(rcvTime.get(i), rcvTime.get(i-1));
			int secondt = DateUtils.SecondsBetween(rcvTime.get(i+1), rcvTime.get(i));
			if(second!=secondt){
				flag=false;
			}
		}
		if(flag){
			 String tableName = "data_quality_analyse";
			 DBObject entity = new BasicDBObject();
			 entity.put("vehicle_id", Integer.valueOf(vehicleInfo.get("id").toString()));
			 entity.put("vehicle_no",vehicleInfo.get("vehicleno"));
			 entity.put("vehicle_color",vehicleInfo.get("vehiclecolor"));
			 entity.put("platform_id", vehicleInfo.get("platformid"));
			 entity.put("area_id", vehicleInfo.get("areaid"));
			 entity.put("enterprise_id",vehicleInfo.get("enterpriseid")==null?1:Integer.valueOf(vehicleInfo.get("enterpriseid").toString()));
			 entity.put("exception_time", DateUtils.getPreviousDayDate());
			 entity.put("exception_type", 1);
			 entity.put("exception_content", "轨迹接收时间无变化");
			 egovMongoTemplate.insert(entity, tableName);
		}
	}
	/**
	 * 分析gps速度
	 * @param gpsSpeed
	 */
	public void analyseGpsSpeed(List<Integer> gpsSpeed,Map<String,Object> vehicleInfo){
		logger.info("分析车辆  :"+vehicleInfo.get("id")+" gps速度");
		boolean flag = true;
		for(int i=1;i<gpsSpeed.size();i++){
			int speed = (int)gpsSpeed.get(i);
			int speedo = (int)gpsSpeed.get(i-1);
			if(speed!=speedo){
				flag=false;
			}
		}
		if(flag){
			 String tableName = "data_quality_analyse";
			 DBObject entity = new BasicDBObject();
			 entity.put("vehicle_id", Integer.valueOf(vehicleInfo.get("id").toString()));
			 entity.put("vehicle_no",vehicleInfo.get("vehicleno"));
			 entity.put("vehicle_color",vehicleInfo.get("vehiclecolor"));
			 entity.put("platform_id", vehicleInfo.get("platformid"));
			 entity.put("area_id", vehicleInfo.get("areaid"));
			 entity.put("enterprise_id",vehicleInfo.get("enterpriseid")==null?1:Integer.valueOf(vehicleInfo.get("enterpriseid").toString()));
			 entity.put("exception_time", DateUtils.getPreviousDayDate());
			 entity.put("exception_type", 1);
			 entity.put("exception_content", "轨迹数据的速度无变化");
			 egovMongoTemplate.insert(entity, tableName);
		}
	}
	/**
	 * 分析状态字是否相同
	 * @param state
	 */
	public void analyseState(List<Integer> state,Map<String,Object> vehicleInfo){
		logger.info("分析车辆  :"+vehicleInfo.get("id")+" 车辆状态字");
		boolean flag = true;
		for(int i=1;i<state.size();i++){
			Integer stat = (Integer)state.get(i);
			Integer stato = (Integer)state.get(i-1);
			if(!stat.equals(stato)){
				flag=false;
			}
			if(C_GPS_FLAG_VALID==(C_GPS_FLAG_VALID & stat)){
				
			}
		}
		if(flag){
			 String tableName = "data_quality_analyse";
			 DBObject entity = new BasicDBObject();
			 entity.put("vehicle_id", Integer.valueOf(vehicleInfo.get("id").toString()));
			 entity.put("vehicle_no",vehicleInfo.get("vehicleno"));
			 entity.put("vehicle_color",vehicleInfo.get("vehiclecolor"));
			 entity.put("platform_id", vehicleInfo.get("platformid"));
			 entity.put("area_id", vehicleInfo.get("areaid"));
			 entity.put("enterprise_id",vehicleInfo.get("enterpriseid")==null?1:Integer.valueOf(vehicleInfo.get("enterpriseid").toString()));
			 entity.put("exception_time", DateUtils.getPreviousDayDate());
			 entity.put("exception_type", 1);
			 entity.put("exception_content", "轨迹数据的状态字无变化");
			 egovMongoTemplate.insert(entity, tableName);
		}
	}
	/**
	 * 分析轨迹是否无盲区
	 * @param state
	 * @param vehicleInfo
	 */
	public void analyseStateValid(List<Integer> state, Map<String,Object> vehicleInfo) {
		logger.info("分析车辆  :"+vehicleInfo.get("id")+" 车辆状态字");
		boolean flag = true;
		for(int i=1;i<state.size();i++){
			Integer stat = (Integer)state.get(i);
			if(C_GPS_FLAG_VALID==(C_GPS_FLAG_VALID & stat)){
				
			}else{
				flag = false;
			}
		}
		if(flag){
			 String tableName = "data_quality_analyse";
			 DBObject entity = new BasicDBObject();
			 entity.put("vehicle_id", Integer.valueOf(vehicleInfo.get("id").toString()));
			 entity.put("vehicle_no",vehicleInfo.get("vehicleno"));
			 entity.put("vehicle_color",vehicleInfo.get("vehiclecolor"));
			 entity.put("platform_id", vehicleInfo.get("platformid"));
			 entity.put("area_id", vehicleInfo.get("areaid"));
			 entity.put("enterprise_id",vehicleInfo.get("enterpriseid")==null?1:Integer.valueOf(vehicleInfo.get("enterpriseid").toString()));
			 entity.put("exception_time", DateUtils.getPreviousDayDate());
			 entity.put("exception_type", 1);
			 entity.put("exception_content", "轨迹数据无盲区");
			 egovMongoTemplate.insert(entity, tableName);
		}
	}
}
